package avicit.bdp.dds.api.controller;

import avicit.bdp.common.dto.query.dds.ExecutorQuery;
import avicit.bdp.dds.dispatch.enums.CommandType;
import avicit.bdp.dds.dispatch.enums.FailureStrategy;
import avicit.bdp.dds.dispatch.enums.Priority;
import avicit.bdp.dds.dispatch.enums.RunMode;
import avicit.bdp.dds.dispatch.enums.TaskDependType;
import avicit.bdp.dds.api.enums.ExecuteType;
import avicit.bdp.dds.api.service.ExecutorService;
import avicit.bdp.dds.common.Constants;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.rest.msg.ResponseMsg;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;

/**
 * @author mayi
 * 流程实例执行处理器
 */
@RestController
@Api(tags = "流程实例执行处理器")
@RequestMapping("/api/bdp/dds/executors")
public class ExecutorRest {
    private static final Logger logger = LoggerFactory.getLogger(ExecutorRest.class);

    @Autowired
    private ExecutorService execService;

    /**
     * 启动工作流
     *
     * @param executorQuery executorQuery
     * @throws ParseException ParseException
     */
    @PostMapping(value = "/start-process-instance")
    @ApiOperation(value = "启动工作流")
    public ResponseMsg<Boolean> startProcessInstance(@RequestBody ExecutorQuery executorQuery) throws ParseException {
        if (executorQuery == null) {
            logger.error("启动工作流,参数为空");
            throw new BusinessException("启动工作流,参数为空");
        }

        logger.info("start process instance,executor query: {}", executorQuery);

        String processDefinitionId = executorQuery.getProcessDefinitionId();
        String scheduleTime = executorQuery.getScheduleTime();
        String startNodeList = executorQuery.getStartNodeList();
        Integer failureStrategy = executorQuery.getFailureStrategy();
        if(failureStrategy == null){
            failureStrategy = FailureStrategy.END.getCode();
        }
        if (executorQuery.getExecType() == null) {
            executorQuery.setExecType(CommandType.START_PROCESS.getCode());
        }
        Integer execType = executorQuery.getExecType();
        Integer warningType = executorQuery.getWarningType();

        Integer timeout = executorQuery.getTimeout();
        if (timeout == null) {
            timeout = Constants.MAX_TASK_TIMEOUT;
        }

        String warningUserIds = executorQuery.getWarningUserIds();
        String workerGroup = executorQuery.getWorkerGroup();

        Integer taskDependType = TaskDependType.TASK_POST.getCode();
        if (executorQuery.getTaskDependType() != null) {
            taskDependType = executorQuery.getTaskDependType();
        }

        Integer processInstancePriority = Priority.MEDIUM.getCode();
        if (executorQuery.getProcessInstancePriority() != null) {
            processInstancePriority = executorQuery.getProcessInstancePriority();
        }

        Integer runMode = RunMode.RUN_MODE_SERIAL.getCode();
        if (executorQuery.getRunMode() != null) {
            runMode = executorQuery.getRunMode();
        }

       execService.execProcessInstance(processDefinitionId, scheduleTime, execType, failureStrategy, startNodeList,
                taskDependType, warningType, warningUserIds, runMode, processInstancePriority, workerGroup, timeout);

        ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(true);
        return responseMsg;
    }

    /**
     * 启动工作流
     *
     * @param executorQuery executorQuery
     * @throws ParseException ParseException
     */
    @PostMapping(value = "/startProcess")
    @ApiOperation(value = "启动工作流")
    public ResponseMsg<String> startProcess(@RequestBody ExecutorQuery executorQuery) throws ParseException {
        if (executorQuery == null) {
            logger.error("启动工作流,参数为空");
            throw new BusinessException("启动工作流,参数为空");
        }

        logger.info("start process instance,executor query: {}", executorQuery);

        String processDefinitionId = executorQuery.getProcessDefinitionId();
        String scheduleTime = executorQuery.getScheduleTime();
        String startNodeList = executorQuery.getStartNodeList();
        Integer failureStrategy = executorQuery.getFailureStrategy();
        if(failureStrategy == null){
            failureStrategy = FailureStrategy.END.getCode();
        }
        if (executorQuery.getExecType() == null) {
            executorQuery.setExecType(CommandType.START_PROCESS.getCode());
        }
        Integer execType = executorQuery.getExecType();
        Integer warningType = executorQuery.getWarningType();

        Integer timeout = executorQuery.getTimeout();
        if (timeout == null) {
            timeout = Constants.MAX_TASK_TIMEOUT;
        }

        String warningUserIds = executorQuery.getWarningUserIds();
        String workerGroup = executorQuery.getWorkerGroup();

        Integer taskDependType = TaskDependType.TASK_POST.getCode();
        if (executorQuery.getTaskDependType() != null) {
            taskDependType = executorQuery.getTaskDependType();
        }

        Integer processInstancePriority = Priority.MEDIUM.getCode();
        if (executorQuery.getProcessInstancePriority() != null) {
            processInstancePriority = executorQuery.getProcessInstancePriority();
        }

        Integer runMode = RunMode.RUN_MODE_SERIAL.getCode();
        if (executorQuery.getRunMode() != null) {
            runMode = executorQuery.getRunMode();
        }

        String id = execService.execProcessInstance(processDefinitionId, scheduleTime, execType, failureStrategy, startNodeList,
                taskDependType, warningType, warningUserIds, runMode, processInstancePriority, workerGroup, timeout);

        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(id);
        return responseMsg;
    }

    /**
     * 暂停/恢复/停止工作流实例
     */
    @GetMapping(value = "/execute")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "processDefinitionId", value = "流程定义id", dataType = "String"),
            @ApiImplicitParam(name = "processInstanceId", value = "流程实例id", dataType = "String")
    })
    @ApiOperation(value = "暂停/恢复/停止工作流实例")
    public ResponseMsg<Boolean> execute(@RequestParam(value = "processDefinitionId", required = false) String processDefinitionId,
                                        @RequestParam(value = "processInstanceId", required = false) String processInstanceId,
                                        @RequestParam("executeType") ExecuteType executeType) {

        logger.info("execute command, process instance id:{}, execute type:{}", processInstanceId, executeType);

        if (StringUtils.isAllBlank(processDefinitionId, processInstanceId)) {
            throw new BusinessException("请检查参数");
        }

        execService.execute(processDefinitionId, processInstanceId, executeType);

        ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(true);
        return responseMsg;
    }


}
